package com.v8dn.app.util.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * @title Excel读工具类
 * @author lhf
 * @date 2012-10-31 下午2:48:41
 */
public class ExcelReadUtil{
	
	private final static String pass="pass";
	private final static String noPass="noPass";
	
	public static void main(String[] args){
		parseToList("d:/报表中心系统接口格式整理.xlsx");
		parseToList("d:/报表中心系统接口格式整理.xls");
	}
	
	private static Log log=LogFactory.getLog(ExcelReadUtil.class);
	
	static{
		log.debug("启动ExcelRead工具类!");
	}
	
	/**
	 * TODO 私用构造主法.因为此类是工具类.
	 */
	public ExcelReadUtil(){
		super();
	}

	/**
	 * @title 解析成List集合
	 * @param filePath
	 * @return 
	 */
	public static List parseToList(String filePath){
		List list=new ArrayList();
		Vector cellV=new Vector();
		Map<Integer,String> sheetMap=new HashMap<Integer,String>();
		Workbook wb=ExcelReadUtil.getWorkBook(filePath);
		for(int i=0;i<wb.getNumberOfSheets();i++){
			Sheet sheet=wb.getSheetAt(i);
			sheetMap.put((i+1),sheet.getSheetName());
			if(pass.equals(thanRowNum(sheet))){
				for(int j=0;j<sheet.getLastRowNum();j++){
					Row row=getRow(sheet,j);
					if(row!=null){
						if(pass.equals(thanColNum(row))){
							for(int k=0;k<row.getLastCellNum();k++){
								Cell cell=getCell(row,k);
								ifType(cell,cellV);
							}
						}
					}
				}
			}
		}
		list.add(sheetMap);
		list.add(cellV);
		return list;
	}
	
	/**
	 * @title 判断大于最大行数
	 * @param sheet
	 * @return
	 */
	private static String thanRowNum(Sheet sheet){
		if(getVersion(sheet)==3){
			if(sheet.getLastRowNum()>=65535){
				log.error("对不起,03版单sheet行数超过65535!!!");
				return noPass;
			}else{
				return pass;
			}
		}else if(getVersion(sheet)==7){
			if(sheet.getLastRowNum()>=1048576){
				log.error("对不起,07版单sheet行数超过1048576!!!");
				return noPass;
			}else{
				return pass;
			}
		}else{
			return noPass;
		}
	}
	
	/**
	 * @title 判断大于最大列数
	 * @param row
	 * @return
	 */
	private static String thanColNum(Row row){
		if(getVersion(row)==3){
			if(row.getLastCellNum()>=255){
				log.error("对不起,03版单sheet列数超过255!!!");
				return noPass;
			}else{
				return pass;
			}
		}else if(getVersion(row)==7){
			if(row.getLastCellNum()>=16384){
				log.error("对不起,07版单sheet列数超过16384!!!");
				return noPass;
			}else{
				return pass;
			}
		}else{
			return noPass;
		}
	}
	
	/**
	 * @title 根据传进来的对象判断是03还是07
	 * @param obj
	 * @return 0:不是poi对象,3:03对象,7:07对象
	 */
	private static int getVersion(Object obj){
		if(obj.getClass().getSimpleName().substring(0,1).equals("H")){
			return 3;
		}else if(obj.getClass().getSimpleName().substring(0,1).equals("X")){
			return 7;
		}else{
			return 0;
		}
	}
	
	/**
	 * @title 判断文件是否存在 
	 * @param filePath 文件路径
	 * @return true:存在,false:不存在
	 */
	private static boolean isExitsFile(String filePath){
		File f=new File(filePath);
		if(f.exists()){
			return true;
		}else{
			log.error(new StringBuffer("[对不起,文件不存在!!!]"));
			return false;
		}
	}
	
	/**
	 * @title 获取文件
	 * @param filePath 文件路径
	 * @return File
	 */
	private static File getFile(String filePath){
		if(isExitsFile(filePath))
			return new File(filePath);
		else 
			return null;
	}
	
	/**
	 * @title 获取文件输入流
	 * @param filePath 文件路径
	 * @return FileInputStream
	 */
	private static FileInputStream getInputStream(String filePath){
		try{
			return new FileInputStream(getFile(filePath));
		}catch(FileNotFoundException e){
			log.error(new StringBuffer("[").append(e.getMessage()).append("]").append(e.getCause()));
		}
		return null;
	}
	
	/**
	 * @title 创建workbook,根据不同版本获得不同版本的workbook
	 * @param filePath 文件路径
	 * @return Workbook
	 */
	public static Workbook getWorkBook(String filePath){
		try{
			if(isExitsFile(filePath)){
				if(filePath.endsWith("xls")){//03版本
					return new HSSFWorkbook(getInputStream(filePath));
				}else if(filePath.endsWith("xlsx")){//07版本
					return new XSSFWorkbook(getInputStream(filePath));
				}else{
					return null;
				}
			}else{
				return null;
			}
		}catch(Exception e){
			log.error(new StringBuffer("[").append(e.getMessage()).append("]").append(e.getCause()));
		}
		return null;
	}
	
	/**
	 * @title 获取sheet
	 * @param wb
	 * @param sheetNum sheet页数(从0开始)
	 * @return Sheet
	 */
	public static Sheet getSheet(Workbook wb,int sheetNum){
		return wb.getSheetAt(sheetNum);
	}
	
	/**
	 * @title 获取row
	 * @param sheet
	 * @param rowNum 行数(从0开始)
	 * @return
	 */
	public static Row getRow(Sheet sheet,int rowNum){
		return sheet.getRow(rowNum);
	}
	
	/**
	 * @title 获取cell
	 * @param row
	 * @param cellNum 当前单元格数(从0开始)
	 * @return
	 */
	public static Cell getCell(Row row,int cellNum){
		return row.getCell(cellNum);
	}
	
	/**
	 * @title 判断单元格类型
	 * @param cell 单元格对象
	 */
	private static void ifType(Cell cell){
		//单元格类型
		int cellType=cell.getCellType();
		if(cellType==Cell.CELL_TYPE_BLANK){//空
			System.out.println("对不起单元个为空!!!");
		}else if(cellType==Cell.CELL_TYPE_BOOLEAN){//判断
			System.out.println(cell.getBooleanCellValue());
		}else if(cellType==Cell.CELL_TYPE_ERROR){//错误
			System.out.println(cell.getErrorCellValue());
		}else if(cellType==Cell.CELL_TYPE_FORMULA){//公式
			System.out.println(cell.getArrayFormulaRange());
		}else if(cellType==Cell.CELL_TYPE_NUMERIC){//数字
			System.out.println(cell.getNumericCellValue());
		}else if(cellType==Cell.CELL_TYPE_STRING){//字符串
			System.out.println(cell.getStringCellValue());
		}else if(DateUtil.isCellDateFormatted(cell)){//日期
			System.out.println(cell.getDateCellValue());
		}else{
			log.error("走到这里是错误的单元格");
		}
	}
	
	/**
	 * @title 判断单元格类型
	 * @param cell 单元格对象
	 */
	private static void ifType(Cell cell,Vector vector){
		//单元格类型
		int cellType=cell.getCellType();
		if(cellType==Cell.CELL_TYPE_BLANK){//空
			System.out.println("对不起单元个为空!!!");
		}else if(cellType==Cell.CELL_TYPE_BOOLEAN){//判断
			System.out.println(cell.getBooleanCellValue());
			vector.add(cell.getBooleanCellValue());
		}else if(cellType==Cell.CELL_TYPE_ERROR){//错误
			System.out.println(cell.getErrorCellValue());
			vector.add(cell.getErrorCellValue());
		}else if(cellType==Cell.CELL_TYPE_FORMULA){//公式
			System.out.println(cell.getArrayFormulaRange());
			vector.add(cell.getArrayFormulaRange());
		}else if(cellType==Cell.CELL_TYPE_NUMERIC){//数字
			System.out.println(cell.getNumericCellValue());
			vector.add(cell.getNumericCellValue());
		}else if(cellType==Cell.CELL_TYPE_STRING){//字符串
			System.out.println(cell.getStringCellValue());
			vector.add(cell.getStringCellValue());
		}else if(DateUtil.isCellDateFormatted(cell)){//日期
			System.out.println(cell.getDateCellValue());
			vector.add(cell.getDateCellValue());
		}else{
			log.error("走到这里是错误的单元格");
		}
	}
	
}
